<template>
  <div class="pad-t-40" v-loading="saveLoading">
    <el-steps class="pad-lr-20 mar-b-40" :active="stepActive - 1" finish-status="success">
      <el-step v-for="step in steps" :title="step" :key="step"></el-step>
    </el-steps>
    <el-container style="height: 400px">
      <el-aside class="h-100p bor-r" style="width: 200px" :class="{'hidden': stepActive > 2}">
        <el-tree ref="tableNameTree" node-key="id" element-loading-text="正在加载中..." v-loading="treeLoading" :accordion="true" :data="tableNamesData" @node-click="handleNodeClick"></el-tree>
      </el-aside>
      <el-main class="h-100p pad-lr-20" :class="{'hidden': stepActive > 2}">
        <el-table ref="multipleTable" height="400" stripe :data="tableData" v-loading="tableLoading" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55"></el-table-column>
          <el-table-column property="name" label="字段名称" width="150"></el-table-column>
          <el-table-column property="type" label="类型" width="200"></el-table-column>
          <el-table-column property="comment" label="注解"></el-table-column>
        </el-table>
      </el-main>
      <el-main class="h-100p pad-lr-20" v-if="stepActive === 3">
        <el-row :gutter="20">
          <el-col class="lh-40 bg-gray-4" :span="10">目标字段</el-col>
          <el-col class="lh-40 bg-gray-4" :span="4">映射</el-col>
          <el-col class="lh-40 bg-gray-4" :span="10">源字段</el-col>
        </el-row>
        <el-row class="bor-b mar-t-10" v-for="item in tableSelects[2]" :gutter="20" :key="item.index">
          <el-col :span="10" class="lh-36"><span class="text-red">*</span> {{treeSelects[2] + '.' + item.name}}</el-col>
          <el-col :span="4">
            <el-select size="medium" v-model="maps[item['name']]['value']" placeholder="请选择">
              <el-option
                v-for="map in mapTo"
                :key="map.value"
                :label="map.name"
                :value="map.value">
              </el-option>
            </el-select>
          </el-col>
          <el-col :span="10">
            <el-select size="medium" v-model="maps[item['name']]['target']" placeholder="请选择">
              <el-option
                v-for="dItem in tableSelects[1]"
                :key="dItem.name"
                :label="treeSelects[1] + '.' + dItem.name"
                :value="dItem.name">
              </el-option>
            </el-select>
          </el-col>
        </el-row>
      </el-main>

      <el-main class="h-100p pad-lr-20" v-if="stepActive === 4">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-tag>[{{treeSelects[1]}}]分区配置</el-tag>
            <configuration :model="sourceForm" :location="location[1]" @save="getSrc"></configuration>
          </el-col>
          <el-col :span="12">
            <el-tag>[{{treeSelects[2]}}]分区配置</el-tag>
            <configuration :model="targetForm" :location="location[2]" @save="getTgt"></configuration>
          </el-col>
        </el-row>
      </el-main>
      <el-main class="h-100p pad-lr-20" v-if="stepActive === 5">
        <el-form class="mar-t-20 pad-r-60" ref="model" :model="model" label-width="80px">
          <el-form-item label="名称" required>
            <el-input v-model="model.name"></el-input>
          </el-form-item>
          <el-form-item label="描述">
            <el-input v-model="model.description"></el-input>
          </el-form-item>
        </el-form>
      </el-main>
    </el-container>
    <el-row class="bor-t pad-t-20">
      <el-col :span="12">
        <el-button v-if="stepActive > 1" @click.stop="setStepActive(true)">上一步</el-button>
      </el-col>
      <el-col class="text-right" :span="12">
        <el-button v-if="stepActive < 5" class="mar-l-20" type="primary" @click.stop="setStepActive(false)">下一步</el-button>
        <el-button v-if="stepActive === 5" class="mar-l-20" type="primary" @click.stop="saveModel">保存</el-button>
      </el-col>
    </el-row>
  </div>
</template>
<script> 
import { mapGetters } from "vuex";

import { griffinService } from '@/api/griffin';

import configuration from './configuration';

export default {
  components: {
    configuration: configuration
  },
  data(){
    return {
      location: {
        1: '',
        2: ''
      },
      saveLoading: false,
      treeLoading: false,
      tableData: [],
      tableLoading: false,
      tablesData: {
        1: [],
        2: []
      },
      treeSelects: {
        1: '',
        2: ''
      },
      mapTo: [
        {name: '等于(=)' , value: '='},
        {name: '不等于(!=)' , value: '!='},
        {name: '大于(>)' , value: '>'},
        {name: '大于等于(>=)' , value: '>='},
        {name: '小于(<)' , value: '<'},
        {name: '小于等于(<=)' , value: '<='}
      ],
      stepActive: 1,
      steps: [],
      tableNamesData: [],
      tableSelects: {
        1: [],
        2: []
      },
      tableSelectIndexs: {
        1: [],
        2: []
      },
      sourceForm: null,
      targetForm: null,
      maps: null,
      model: {
        'dq.type': 'ACCURACY',
        'measure.type': 'griffin',
        'name': '',
        'owner': '',
        'description': '',
        'process.type': 'BATCH',
        'data.sources': [
          {
            'name': 'source',
            'connector': {}
          },
          {
            'name': 'target',
            'connector': {}
          }
        ],
        'evaluate.rule': {
          'rules': [
            {
              'dq.type': 'ACCURACY',
              'dsl.type': 'griffin-dsl',
              'out.dataframe.name': 'accuracy',
              'rule': ''
            }
          ]
        }
      }
    }
  },
  computed: mapGetters(['userInfo']),
  props: {
    measureType: {
      default: null,
      type: Object
    }
  },

  mounted(){
    this.steps = this.measureType.steps || [];
    this.getTableNames();
    this.model.owner = this.userInfo.account;
  },

  methods: {
    getSrc(model){
      this.sourceForm = model;
    },
    getTgt(model){
      this.targetForm = model;
    },
    getTableNames(){
      this.treeLoading = true;
      griffinService.getTableNames().then(
        res => {
          this.treeLoading = false;
          let tableNames = [];
          if(res.data){
            let data = res.data;
            Object.keys(data).forEach(
              keyName => {
                if(data[keyName].length){
                  let dbData = {
                    id: keyName,
                    label: keyName,
                    children: []
                  }
                  data[keyName].forEach(
                    item => {
                      dbData.children.push({
                        id: keyName + '.' + item,
                        label: item,
                        parent: keyName
                      })
                    }
                  )
                  tableNames.push(dbData);
                }
              }
            )
          }
          this.tableNamesData = tableNames;
        }
      ).catch(() => {
        this.getTableNames();
      })
    },
    handleNodeClick(data){
      if(!data['children'] && data.parent){
        if(this.treeSelects[this.stepActive] === data.id){
          return;
        }
        this.treeSelect = data.label;
        this.treeSelects[this.stepActive] = data.id;
        let sources = this.model['data.sources'][this.stepActive - 1];
        let connector = {
          'config': {
            'database': data.parent,
            'table.name': data.label,
            'where': ''
          },
          'data.time.zone': '',
          'data.unit': '',
          'name': sources.name + new Date().getTime(),
          'type': 'HIVE',
          'version': '1.2'
        }
        this.model['data.sources'][this.stepActive - 1]['connector'] = connector
        this.tableData = [];
        this.tableLoading = true;
        griffinService.getTableMetadata({
          db: data.parent,
          table: data.label
        }).then(
          res => {
            this.tableLoading = false;
            if(res.data.sd){
              this.location[this.stepActive] = res.data.sd.location || '';
              let datalist = res.data ? res.data.sd.cols : [];
              datalist.forEach(
                (item , index) => {
                  item['index'] = index;
                }
              )
              this.tablesData[this.stepActive] = datalist;
              this.tableData = this.tablesData[this.stepActive];
            }
          }
        )
      }
    },
    handleSelectionChange(rows){
      this.tableSelectIndexs[this.stepActive] = [];
      rows.forEach(
        row => {
          this.tableSelectIndexs[this.stepActive].push(row.index);
        }
      )
      this.tableSelects[this.stepActive] = rows;
    },
    setMaps(name){
      let oldMaps = this.maps || {};
      let result = {
        target: '',
        value: ''
      }
      if(oldMaps[name]){
        result.value = oldMaps[name].value;
        this.tableSelects[1].forEach(
          item => {
            if(item.name === oldMaps[name].target){
              result.target = item.name;
            }
          }
        )
      }
      return result;
    },
    setStepActive(prev){

      if(prev && this.stepActive > 1){
        this.stepActive--;
      }
      if(prev === false && this.stepActive < this.steps.length){

        if(this.stepActive === 1 || this.stepActive === 2){
          if(this.tableSelects[this.stepActive].length){
            if(this.stepActive === 2){
              let maps = {};
              this.tableSelects[2].forEach(
                item => {
                  maps[item.name] = this.setMaps(item.name);
                }
              )
              this.maps = maps;
            }
            this.stepActive++;
          }else{
            this.$message({
              type: 'error',
              message: '请至少选择一个属性!'
            })
          }
        }else if(this.stepActive === 3){
          let notNull = true;
          Object.values(this.maps).forEach(
            item => {
              if(!item.value || !item.target){
                notNull = false;
              }
            }
          )
          if(notNull){
            this.stepActive++;
          }else{
            this.$message({
              type: 'error',
              message: '请完整填写表单'
            })
          }

        }else{
          this.stepActive++;
        }

      }

      if(this.stepActive <= 2){
        this.$refs.tableNameTree.setCurrentKey(this.treeSelects[this.stepActive] || null);
        let tableSelectIndexs = this.tableSelectIndexs[this.stepActive];
        this.tableData = this.tablesData[this.stepActive];
        this.$refs.multipleTable.clearSelection();
        setTimeout(() => {
          tableSelectIndexs.forEach(
            index => {
              this.$refs.multipleTable.toggleRowSelection(this.tableData[index] , true);
            }
          )
        })
      }

    },
    getRuleText(){
      let rule = [];
      Object.keys(this.maps).forEach(
        name => {
          let item = this.maps[name];
          rule.push(`source.${item.target}${item.value}target.${name}`);
        }
      );
      return rule.join(' AND ');
    },
    saveModel(){
      if(!this.model.name){
        this.$message({
          type: 'error',
          message: '指标名称不能为空'
        });
        return false;
      }else{
        if(!this.$store.state.dag.projectId || !this.$store.state.dag.projectName){
          this.$message({
            type: 'error',
            message: '数据错误，请返回项目重新进入。'
          });
          return false;
        }
        this.model['data.sources'][0]['connector']['config']['where'] = this.sourceForm.where;
        this.model['data.sources'][1]['connector']['config']['where'] = this.targetForm.where;

        this.model['data.sources'][0]['connector']['data.unit'] = this.sourceForm['data.unit'];
        this.model['data.sources'][1]['connector']['data.unit'] = this.targetForm['data.unit'];

        this.model['data.sources'][0]['connector']['data.time.zone'] = this.sourceForm['data.time.zone'];
        this.model['data.sources'][1]['connector']['data.time.zone'] = this.targetForm['data.time.zone'];

        if(this.sourceForm['predicates']){
          this.model['data.sources'][0]['connector']['predicates'] = this.sourceForm['predicates'];
        }

        if(this.targetForm['predicates']){
          this.model['data.sources'][1]['connector']['predicates'] = this.targetForm['predicates'];
        }

        this.model['evaluate.rule'].rules[0]['rule'] = this.getRuleText();
        
        this.saveLoading = true;
        griffinService.saveMeasures({
          ...this.model,
          'projectId': this.$store.state.dag.projectId,
          'projectName': this.$store.state.dag.projectName
        }).then(
          () => {
            this.saveLoading = false;
            this.$message({
              type: 'success',
              message: '保存成功'
            });
            this.$emit('back');
          }
        ).catch(() => {
          this.saveLoading = false;
        })

      }
    }
  }

}
</script>